package com.linhngua.code.hibernate.core;

import java.io.Serializable;
import java.util.Collection;

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Order;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Repository;

/**
 * 
 * @author tranxl sample implementation
 * @param <Key>
 * @param <Entity>
 */

@Configuration
@Repository
public class HibernateOracleDataAccess<Key extends Serializable, Entity>
		implements HibernateDataAccess<Key, Entity> {
	
	private SessionFactory	sessionFactory;
	
	public HibernateOracleDataAccess(SessionFactory sessionFactory) {

		super();
		this.sessionFactory = sessionFactory;
	}
	
	@SuppressWarnings("unchecked")
	public Collection<Entity> loadAll(Class<Entity> klass) {

		Session session = sessionFactory.getCurrentSession();
		Criteria criteria = session.createCriteria(klass);
		criteria.addOrder(Order.asc("id"));
		session.clear();
		return criteria.list();
		
	}
	
	@Override
	public Entity load(Key key, Class<Entity> klass) {

		try {
			Entity entity = klass.newInstance();
			Session session = sessionFactory.getCurrentSession();
			session.load(entity, key);
			return entity;
		}
		catch (Exception ex) {
			throw new RuntimeException(ex);
		}
		
	}
	
	@Override
	public void save(Entity entity) {

		Session session = sessionFactory.getCurrentSession();
		session.save(entity);
		
	}
	
	@Override
	public void update(Entity entity) {

		Session session = sessionFactory.getCurrentSession();
		session.update(entity);
		
	}
	
	@Override
	public void saveOrUpdate(Entity entity) {

		Session session = sessionFactory.getCurrentSession();
		session.saveOrUpdate(entity);
		
	}
	
	@Override
	public void delete(Entity entity) {

		Session session = sessionFactory.getCurrentSession();
		session.delete(entity);
		
	}
	
	@Override
	public SessionFactory getSessionFactory() {

		return sessionFactory;
	}
	
	@Override
	public void close() {

		if (sessionFactory != null) {
			sessionFactory.close();
		}
		
	}
}
